using System;
using System.Collections.Generic;

using Common.Logging;
using Common.Caching;
using System.Threading;
using System.Security;

using BancoX.Dominio;

namespace BancoX.Servicios
{
    public interface IServicioConsultas
    {
        IList<CuentaBancaria> ObtenerCuentas(string dni);
        IList<Prestacion> ObtenerPrestaciones();
        IList<Operacion> ObtenerOperaciones(string numeroCuenta);
    }

    public class ServicioConsultas : IServicioConsultas
    {
        #region Propiedades
        private IRepositorioOperaciones _repositorioOperaciones;
        public IRepositorioOperaciones RepositorioOperaciones
        {
            set { _repositorioOperaciones = value; }
        }

        private IRepositorioCuentas _repositorioCuentas;
        public IRepositorioCuentas RepositorioCuentas
        {
            set { _repositorioCuentas = value; }
        }

        private IRepositorioPrestaciones _repositorioPrestaciones;
        public IRepositorioPrestaciones RepositorioPrestaciones
        {
            set { _repositorioPrestaciones = value; }
        }
        #endregion Propiedades

        #region IServicioConsultas
        public IList<CuentaBancaria> ObtenerCuentas(string dni)
        {
            if (Thread.CurrentPrincipal == null)
                throw new SecurityException("Usuario no autenticado");

            _logger.Info("Consulta de cuentas");

            return this._repositorioCuentas.ObtenerCuentasPorCliente(dni);
        }

        public IList<Prestacion> ObtenerPrestaciones()
        {
            if (Thread.CurrentPrincipal == null)
                throw new SecurityException("Usuario no autenticado");

            _logger.Info("Consulta de Prestaciones");

            string clave = "prestaciones";

            object dato = _cache.Get(clave);
            if (dato == null)
            {
                dato = _repositorioPrestaciones.ObtenerPrestaciones();
                _cache.Add(clave, dato);
            }
            return dato as IList<Prestacion>;
        }

        public IList<Operacion> ObtenerOperaciones(string numeroCuenta)
        {
            if (Thread.CurrentPrincipal == null)
                throw new SecurityException("Usuario no autenticado");

            _logger.Info("Consulta de operaciones");

            string clave = "operacionescuenta" + numeroCuenta;

            object dato = _cache.Get(clave);
            if (dato == null)
            {
                dato = _repositorioOperaciones.ObtenerOperaciones(numeroCuenta);
                _cache.Add(clave, dato);
            }
            return dato as IList<Operacion>;
        }
        #endregion

        #region Infraestructura
        private ILog _logger = LogManager.GetLogger("BancoX.Servicios");
        private ICache _cache = CacheManager.GetCache("BancoX.Servicios");
        #endregion
    }
}
